home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_217 / snipit / hand.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  12KB  |  574 lines

  1. /* :ts=4
  2.  *
  3.  * Amiga SnipIt 1.2
  4.  * (c) (opyright 1987,1988 - Scott Evernden - All Rights Reserved
  5.  * 
  6.  * hand.c - input event handler & snipper & lib function replacements
  7.  *
  8.  */
  9.  
  10. #include "hs.h"
  11.  
  12. int state;                    /* mouse state */
  13. int snip;                    /* container type which is highlighted */
  14. int maxx, maxy;                /* maximum cells in snipped layer */
  15. int origx, origy;            /* pixel origin in conunit */
  16. int charx, chary;            /* pixel size of char cell of conunit */
  17. int lastx, lasty;            /* last cell highlighted */
  18. int con_offx, con_offy;        /* correction offsets for console windows */
  19. int win_offx, win_offy;        /* correction offsets for non-console windows */
  20. int snipx[2], snipy[2];        /* snip area; top/left to bottom/right */
  21. int left, right;            /* sides of snip area, irrespective of rows */
  22.  
  23. struct TextFont *capttf;    /* non-NULL indicates recognition required */
  24. struct Window *snipw;        /* clipped text window */
  25. struct RastPort *sniprp;    /* rastport of clipped text window */
  26.  
  27. struct RastPort captrp;        /* rastport holding clipped snip area */
  28. struct BitMap captbm;        /* bitmap into which snipped area is copied */
  29. int captx, capty;            /* dimensions of capture map */
  30. int jobFlag;                /* flag input handler to ignore mouse events */
  31. int lock_layer;                /* lock window/console layer while snipping */
  32. int windows=1;                /* include windows in layer search */
  33.  
  34. int cmd1 = IEQUALIFIER_LCOMMAND;
  35. int cmd2 = IEQUALIFIER_LALT;
  36.  
  37. extern struct IntuitionBase *IntuitionBase;
  38. extern struct ConsoleBase *ConsoleBase;
  39. extern struct Task *myTask;
  40. extern int mySignal;
  41.  
  42. /* this does one at a time */
  43. struct InputEvent *doEvent();
  44.  
  45. /*********************************************/
  46. #asm
  47.  
  48.     public    _geta4
  49.  
  50. ; Trap these Gfx/Intui functions; purpose is to remove hilighting, if nec.
  51. ; Not all possible cases are handled (window resizing, for example), but
  52. ; the most common ones are.
  53.  
  54.     public    _myRectFill
  55.     public    _myScrollRaster
  56.     public    _myCloseWindow
  57.  
  58.     public    _oldRectFill
  59.     public    _oldScrollRaster
  60.     public    _oldCloseWindow
  61.  
  62. _myRectFill:            ; pardon me
  63.     move.l    a4,-(sp)
  64.     jsr        _geta4                ; establish addressing
  65.     tst.w    _snip
  66.     beq.s    1$                    ; no highlighted area; get out
  67.     cmpa.l    _sniprp,a1
  68.     bne.s    1$                    ; not the same RastPort; get out
  69.     movem.l    a1/d0-d5,-(sp)
  70.     jsr        _clearHi            ; de-highlight
  71.     movem.l    (sp)+,a1/d0-d5
  72. 1$:    movea.l    _oldRectFill,a0
  73.     movea.l    (sp)+,a4
  74.     jmp        (a0)                ; continue into library
  75.  
  76. _myScrollRaster:        ; 'scuse
  77.     move.l    a4,-(sp)
  78.     jsr        _geta4
  79.     tst.w    _snip
  80.     beq.s    1$
  81.     cmpa.l    _sniprp,a1
  82.     bne.s    1$
  83.     movem.l    a1/d0-d5,-(sp)
  84.     jsr        _clearHi
  85.     movem.l    (sp)+,a1/d0-d5
  86. 1$:    movea.l    _oldScrollRaster,a0
  87.     movea.l    (sp)+,a4
  88.     jmp        (a0)
  89.  
  90. _myCloseWindow:
  91.     move.l    a4,-(sp)
  92.     jsr        _geta4
  93.     tst.w    _snip
  94.     beq.s    1$
  95.     cmpa.l    _snipw,a0
  96.     bne.s    1$                    ; not the same Window; get out
  97.     clr.w    _snip
  98.     clr.l    _capttf                ; Window closing; reset indicators
  99. 1$:    movea.l    _oldCloseWindow,a1
  100.     movea.l    (sp)+,a4
  101.     jmp        (a1)
  102.  
  103. ;************************
  104.  
  105. ; input event stream glue
  106.     public    _handlerCode
  107.  
  108. _handlerCode:
  109.     movem.l    d2/d3/a0/a1/a4/a6,-(sp)    ; i think this is right
  110.     jsr        _geta4
  111.     jsr        _myHandler
  112.     movem.l    (sp)+,d2/d3/a0/a1/a4/a6
  113.     rts
  114.  
  115. #endasm
  116. /*********************************************/
  117.  
  118. /* SnipIt's input event handler */
  119. struct InputEvent *myHandler(d2, d3, ev)
  120. long d2, d3;
  121. register struct InputEvent *ev;
  122. {
  123.     register struct InputEvent *inev, **evp;
  124.     struct InputEvent *outev;
  125.  
  126.     if (jobFlag)
  127.         return ev;
  128.  
  129.     inev = ev;
  130.     outev = NULL;
  131.  
  132.     /* back-pointer */
  133.     evp = &outev;
  134.  
  135.     /*
  136.      * Loop thru the possibly linked list of events.
  137.      * We remove the ones having meaning to SnipIt, and leave the others
  138.      */
  139.     while (inev) {
  140.         ev = inev;
  141.         inev = ev->ie_NextEvent;
  142.  
  143.         /* ensure that main code isn't running and this is a mouse event */
  144.         if (ev->ie_Class == IECLASS_RAWMOUSE)
  145.             ev = doEvent(ev);
  146.  
  147.         /* patch back-pointer */
  148.         if (*evp = ev)
  149.             evp = &ev->ie_NextEvent;
  150.     }
  151.  
  152.     /* pass 'em along */
  153.     return outev;
  154. }
  155.  
  156. /*********************************************/
  157.  
  158. /* handle a single (mouse) input event */
  159. struct InputEvent *doEvent(ev)
  160. register struct InputEvent *ev;
  161. {
  162.     static int lflag, rflag, cmd;
  163.     register UWORD code;
  164.     register int x, y;
  165.  
  166.     x = ev->ie_X;
  167.     y = ev->ie_Y;
  168.     code = ev->ie_Code;
  169.  
  170.     /* in mid-snip? */
  171.     if (lflag && code == IECODE_NOBUTTON &&
  172.                             (ev->ie_Qualifier & IEQUALIFIER_LEFTBUTTON)) {
  173.  
  174.         mouse(M_MOVE, x, y);
  175.         return ev;
  176.     }
  177.  
  178.     /* button transition event... */
  179.     code &= ~IECODE_UP_PREFIX;
  180.  
  181.     /* mouse button down event? */
  182.     if ((ev->ie_Code & IECODE_UP_PREFIX) == 0)  {
  183.  
  184.         if (cmd = ev->ie_Qualifier & (cmd1 | cmd2)) {
  185.  
  186.             if (!rflag && code == IECODE_LBUTTON) {
  187.                 lflag++;
  188.                 mouse(M_DOWN, x, y);
  189.             }
  190.  
  191.             else if (!lflag && code == IECODE_RBUTTON)
  192.                 rflag++;        /* note transition */
  193.  
  194.             return NULL;
  195.         }
  196.     }
  197.  
  198.     /* release of left mouse button? */
  199.     else if (lflag && code == IECODE_LBUTTON) {
  200.         lflag = 0;
  201.         mouse(M_UP, x, y);
  202.         return NULL;
  203.     }
  204.  
  205.     /* release of right mouse button? */
  206.     else if (rflag && code == IECODE_RBUTTON) {
  207.         rflag = 0;
  208.  
  209.         /* kick main code */
  210.         jobFlag = cmd;
  211.         Signal(myTask, 1L << mySignal);    
  212.         return NULL;
  213.     }
  214.  
  215.     /* event back into stream */
  216.     return ev;
  217. }
  218.  
  219. /*********************************************/
  220.  
  221. /* find a console containing the layer holding (x,y); return success flag */
  222. int whichConsole(layer, x, y)
  223. struct Layer *layer;
  224. int x, y;
  225. {
  226.     register struct ConUnit *cu, *rcu;
  227.     register struct Node *node;
  228.  
  229.     /* result conunit */
  230.     rcu = NULL;
  231.  
  232.     _Forbid();
  233.  
  234.     /* begin at the beginning */
  235.     node = ConsoleBase->conUnits.lh_Head;
  236.  
  237.     /* next is NULL when back at listhead */
  238.     while (node->ln_Succ) {
  239.         cu = (struct ConUnit *) node;
  240.  
  241.         /* see if console window's layer is the same */
  242.         if (cu && cu->cu_Window && cu->cu_Window->RPort->Layer == layer) {
  243.             rcu = cu;    /* found it */
  244.             break;
  245.         }
  246.  
  247.         node = node->ln_Succ;
  248.     }
  249.  
  250.     Permit();
  251.  
  252.     if (rcu) {
  253.         snip = CON_SNIP;
  254.         snipw = rcu->cu_Window;
  255.         sniprp = snipw->RPort;
  256.         charx = rcu->cu_XRSize;
  257.         chary = rcu->cu_YRSize;
  258.         origx = rcu->cu_XROrigin;
  259.         origy = rcu->cu_YROrigin;
  260.         maxx = rcu->cu_XMax;
  261.         maxy = rcu->cu_YMax;
  262.     }
  263.  
  264.     return rcu != NULL;
  265. }
  266.  
  267. /*********************************************/
  268.  
  269. /* find a window containing the layer holding (x,y); return success flag */
  270. int whichWindow(s, layer, x, y)
  271. struct Screen *s;
  272. struct Layer *layer;
  273. int x, y;
  274. {
  275.     register struct Window *w, *rw;
  276.  
  277.     if (!windows)
  278.         return NULL;
  279.  
  280.     /* result window */
  281.     rw = NULL;
  282.  
  283.     _Forbid();
  284.  
  285.     w = s->FirstWindow;
  286.     while (w) {
  287.         if (w->WLayer == layer) {
  288.             rw = w;
  289.             break;
  290.         }
  291.  
  292.         w = w->NextWindow;
  293.     }
  294.  
  295.     Permit();
  296.  
  297.     if (rw) {
  298.         snip = WIN_SNIP;
  299.         snipw = rw;
  300.         sniprp = snipw->RPort;
  301.         charx = sniprp->Font->tf_XSize;
  302.         chary = sniprp->Font->tf_YSize;
  303.         origx = rw->BorderLeft;
  304.         origy = rw->BorderTop;
  305.         maxx = (rw->Width - rw->BorderRight - origx) / charx - 1;
  306.         maxy = (rw->Height - rw->BorderBottom - origy) / chary - 1;
  307.     }
  308.  
  309.     return rw != NULL;
  310. }
  311.  
  312. /*********************************************/
  313.  
  314. /* handle meaningful mouse activity */
  315. mouse(event, mx, my)
  316. int event;
  317. register int mx, my;
  318. {
  319.     static struct Screen *s;
  320.     static struct Layer *layer;
  321.  
  322.     if (event == M_DOWN)
  323.         s = IntuitionBase->FirstScreen;
  324.  
  325.     /* correct raw positions according to this screen */
  326.     if (!(s->ViewPort.Modes & LACE))
  327.         my /= 2;
  328.  
  329.     mx += s->MouseX - 2;        /* accumulate deltas */
  330.     my += s->MouseY - 1;        /* x,y adjusted for feel */
  331.  
  332.     if (event == M_DOWN) {
  333.  
  334.         /* de-hilight, if nec. */
  335.         if (snip)
  336.             hiSnip(0);
  337.  
  338.         /* turn flag off */
  339.         snip = 0;
  340.  
  341.         /* locate pointed-at layer */
  342.         if ((layer = WhichLayer(&s->LayerInfo, (long) mx, (long) my)) &&
  343.             (whichConsole(layer, mx, my) || whichWindow(s, layer, mx, my))) {
  344.  
  345.             /* if mouse down in title line area, remain clear */
  346.             if (my - snipw->TopEdge < origy)
  347.                 snip = 0;
  348.         }
  349.     }
  350.  
  351.     /* nothing interesting */
  352.     if (!snip)
  353.         return;
  354.  
  355.     /* mouse to window-relative cell coordinates */
  356.     mx = (mx - snipw->LeftEdge - origx) / charx;
  357.     if (mx < 0)
  358.         mx = 0;
  359.     else if (maxx < mx)
  360.         mx = maxx;
  361.  
  362.     my = (my - snipw->TopEdge  - origy) / chary;
  363.     if (my < 0)
  364.         my = 0;
  365.     else if (maxy < my)
  366.         my = maxy;
  367.  
  368.     /* highlighting games ahead */
  369.  
  370.     if (event == M_DOWN) {
  371.         state = M_DOWN;
  372.         if (lock_layer)
  373.             LockLayerRom(layer);
  374.  
  375.         snipx[0] = mx;
  376.         snipy[0] = my;
  377.         hiLite(mx, my, 1, 1);
  378.     }
  379.  
  380.     else if (event == M_UP) {
  381.         snipx[1] = mx;
  382.         snipy[1] = my;
  383.         if (state == M_MOVE)
  384.             hiLite(lastx, lasty, 1, 1);
  385.         hiLite(snipx[0], snipy[0], 1, 1);
  386.         hiSnip(charx == 8);
  387.  
  388.         state = M_UP;
  389.         if (charx != 8)        /* only able to do 8 pixel wide fonts */
  390.             clearHi();
  391.  
  392.         if (lock_layer)
  393.             UnlockLayerRom(layer);
  394.     }
  395.  
  396.     else if (mx != lastx || my != lasty) {
  397.         if (state == M_MOVE)
  398.             hiLite(lastx, lasty, 1, 1);
  399.         hiLite(lastx = mx, lasty = my, 1, 1);
  400.         state = M_MOVE;
  401.     }
  402. }
  403.  
  404. /*********************************************/
  405.  
  406. /* de-highlight; snip is known to be set */
  407. clearHi()
  408. {
  409.     if (state == M_UP)
  410.         hiSnip(0);
  411.  
  412.     else if (lock_layer)
  413.         return;
  414.  
  415.     else {
  416.         hiLite(snipx[0], snipy[0], 1, 1);
  417.         if (state == M_MOVE)
  418.             hiLite(lastx, lasty, 1, 1);
  419.     }
  420.  
  421.     snip = 0;
  422. }
  423.  
  424. /*********************************************/
  425.  
  426. /* local cleanup for this module */
  427. finiHand()
  428. {
  429.     int i;
  430.     PLANEPTR p;
  431.  
  432.     if (snip)
  433.         clearHi();
  434.  
  435.     if (p = captbm.Planes[0])
  436.         FreeRaster(p, (long) captx, (long) capty);
  437. }
  438.  
  439. /*********************************************/
  440.  
  441. /* manufacture rastport with bitmap, ready to receive captured bitmap */
  442. int allocMap(sx, sy)
  443. int sx, sy;
  444. {
  445.     PLANEPTR p;
  446.  
  447.     /* release previous, if any */
  448.     if (p = captbm.Planes[0]) {
  449.         FreeRaster(p, (long) captx, (long) capty);
  450.         captbm.Planes[0] = NULL;
  451.     }
  452.  
  453.     /* record new map size */
  454.     captx = sx;
  455.     capty = sy;
  456.  
  457.     /* build new bitmap to contain snipped area */
  458.     InitBitMap(&captbm, 1L, (long) captx, (long) capty);
  459.     InitRastPort(&captrp);
  460.     captrp.BitMap = &captbm;
  461.  
  462.     /* allocate bitmap planes */
  463.     p = (PLANEPTR) AllocRaster((long) captx, (long) capty);
  464.     if (!p)
  465.         return 0;
  466.  
  467.     captbm.Planes[0] = p;
  468.     return 1;
  469. }
  470.  
  471. /*********************************************/
  472.  
  473. /* video reverse the capture area; perform capture if flagged */
  474. hiSnip(capt)
  475. int capt;
  476. {
  477.     register int px, py, qx, qy, tx, ty;
  478.     long ox, oy;
  479.  
  480.     /* need these vars to be handy */
  481.     tx = maxx;
  482.  
  483.     /* take care of backward snip areas */
  484.     if (snipy[0] < snipy[1] ||
  485.         snipy[0] == snipy[1] && snipx[0] <= snipx[1]) {
  486.  
  487.         px = snipx[0];
  488.         py = snipy[0];
  489.         qx = snipx[1];
  490.         qy = snipy[1];
  491.     }
  492.     else {
  493.         px = snipx[1];
  494.         py = snipy[1];
  495.         qx = snipx[0];
  496.         qy = snipy[0];
  497.     }
  498.  
  499.     /* only if capturing more than 1 cell... */
  500.     if (capt && (px != qx || py != qy)) {
  501.  
  502.         /* left and right sides */
  503.         left = px;
  504.         right = qx;
  505.  
  506.         /* get a new bitmap */
  507.         if (allocMap((tx + 1) * charx, (qy - py + 1) * chary)) {
  508.  
  509.             /* copy console contents into snip-map */
  510.             ox = origx;
  511.             oy = origy + py * chary;
  512.  
  513.             if (snip == CON_SNIP) {        /* user-specified corrections */
  514.                 ox += con_offx;
  515.                 oy += con_offy;
  516.             }
  517.             else {
  518.                 ox += win_offx;
  519.                 oy += win_offy;
  520.             }
  521.  
  522.             ClipBlit(sniprp, ox, oy, &captrp, 0L, 0L,
  523.                             (long) captx, (long) capty, 0xC0L);
  524.  
  525.             /* note new info in snip-map */
  526.             capttf = sniprp->Font;
  527.         }
  528.  
  529.         else {
  530.             /* no memory, act dumb */
  531.             snip = captx = capty = 0;
  532.             return;
  533.         }
  534.     }
  535.  
  536.     /* perform hilighting */
  537.     while (py <= qy) {
  538.  
  539.         if (py == qy)
  540.             tx = qx;
  541.  
  542.         hiLite(px, py, tx - px + 1, 1);
  543.  
  544.         px = 0;
  545.         py++;
  546.     }
  547. }
  548.  
  549. /*********************************************/
  550.  
  551. /* low-lever video reverser */
  552. hiLite(x, y, xs, ys)
  553. int x, y, xs, ys;
  554. {
  555.     register long ox, oy;
  556.  
  557.     ox = origx + x * charx;
  558.     oy = origy + y * chary;
  559.  
  560.     if (snip == CON_SNIP) {        /* user-specified corrections */
  561.         ox += con_offx;
  562.         oy += con_offy;
  563.     }
  564.     else {
  565.         ox += win_offx;
  566.         oy += win_offy;
  567.     }
  568.  
  569.     ClipBlit(sniprp, ox, oy,  sniprp, ox, oy,
  570.                         (long) (xs * charx), (long) (ys * chary), 0x50L);
  571. }
  572.  
  573. /*********************************************/
  574.